﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using Moq;

namespace Yamfinder.Data.Tests
{
    [TestClass]
    public class LexicalEntrySerialiserTests
    {
        private Mock<IDataDictonaryRepository> _dataDicRepoMock;

        private IBsonSerializer GetLexicalSerialiser()
        {
            //Create new Moq object
            _dataDicRepoMock = new Mock<IDataDictonaryRepository>();

            //Return object for testing
            return new LexicalEntrySerialiser(_dataDicRepoMock.Object);
        }

        [TestMethod]
        public void SetDocumentIdSetsTheDocumentId()
        {
            var document = new LexicalEntry();
            var id = ObjectId.GenerateNewId();

            var serialiser = GetLexicalSerialiser();

            serialiser.SetDocumentId(document,id);

            Assert.AreEqual(document.Id, id);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void SetDocumentIdThrowsExceptionIfObjectIsNotLexicalEntry()
        {
            var document = new Object();
            var id = ObjectId.GenerateNewId();

            var serialiser = GetLexicalSerialiser();

            serialiser.SetDocumentId(document, id);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void GetDocumentIdThrowsExceptionIfObjectIsNotLexicalEntry()
        {
            var document = new Object();
            object id;
            Type outType;
            IIdGenerator outGenerator;

            var serialiser = GetLexicalSerialiser();

            serialiser.GetDocumentId(document, out id, out outType, out outGenerator);
        }

        [TestMethod]
        public void GetDocumentIdGetsTheDocumentId()
        {
            var document = new LexicalEntry();
            object id;
            Type outType;
            IIdGenerator outGenerator;

            var serialiser = GetLexicalSerialiser();

            serialiser.GetDocumentId(document, out id, out outType, out outGenerator);

            Assert.AreEqual(document.Id, (ObjectId) id);
            Assert.AreEqual(outType, typeof(ObjectId));
        }

        [TestMethod]
        public void TestDeserialiseWithStrings()
        {
            var lexicalEntry = new LexicalEntry()
                                   {Id = ObjectId.GenerateNewId(), Fields = new Dictionary<string, object>()};
            lexicalEntry.Fields.Add("testfield1", "testfield1value");
            lexicalEntry.Fields.Add("testfield2", "testfield2value");
            lexicalEntry.Fields.Add("testfield3", "testfield3value");

            var serialiser = GetLexicalSerialiser();

            _dataDicRepoMock.Setup(x => x.Get(It.IsAny<string>())).Returns(new DataDictonaryEntry(){Type = "Text"});

            BsonSerializer.RegisterSerializer(typeof(LexicalEntry),serialiser);

            var json = lexicalEntry.ToJson();

            Assert.IsTrue(json.Contains("testfield2value"));
        }
    }
}
